﻿using System;
using System.Configuration;
using Citi.Scheduler.Domain;
using Citi.Scheduler.Wcf.DataContracts;
using System.IO;

namespace Citi.Scheduler.Wcf
{
    public class Monitor : IMonitor
    {
        private static string RunningFile { get { return ConfigurationManager.AppSettings["RunningFile"]; } }

        public RoutineExecutionStatus GetStatus(int routineExecutionId)
        {
            return (RoutineExecutionStatus)GetLastHistory(routineExecutionId).Status;
        }

        public RoutineExecutionHistoryDataContract GetLastHistory(int routineExecutionId)
        {
            var routineExecution = new RoutineExecution().SelectById<RoutineExecution>(routineExecutionId);

            return new RoutineExecutionHistoryDataContract(routineExecution.LastHistory);
        }

        public RoutineExecutionDataContract GetRoutineExecuting(int machineId)
        {
            return GetRoutineInProgress(machineId, null);
        }

        public RoutineExecutionDataContract GetRoutineExecutingByMachineHostname(string hostname)
        {
            return GetRoutineInProgress(null, hostname);
        }

        public bool IsMachineRunningRoutine(int machineId)
        {
            return MachineIsRunning(machineId, null);
        }

        public bool IsMachineRunningRoutineByMachineHostname(string hostname)
        {
            return MachineIsRunning(null, hostname);
        }

        private RoutineExecutionDataContract GetRoutineInProgress(int? machineId, string hostname)
        {
            var machine = SelectMachine(machineId, null);
            return new RoutineExecutionDataContract(machine.RoutineInProgress);
        }

        private bool MachineIsRunning(int? machineId, string hostname)
        {
            var machine = SelectMachine(machineId, null);

            if (machine.RoutineInProgress != null) return true;

            var runningFile = machine.HostName.ToUpper() == Environment.MachineName.ToUpper()
                ? string.Format(RunningFile, @"C:")
                : string.Format(RunningFile, string.Format(@"\\{0}\C$", machine.FullName));

            return File.Exists(runningFile);
        }

        private Machine SelectMachine(int? machineId, string hostname)
        {
            var machine = string.IsNullOrWhiteSpace(hostname)
                ? new Machine().SelectById<Machine>(machineId.Value)
                : new Machine().GetByHostName(hostname, MachineCenter.None);

            if (machine == null)
                throw new Exception(string.Format("Machine not found or does not exist. Verify if the name/id is correct. Id/Host: {0}",
                    machineId == null ? hostname : machineId.Value.ToString()));

            return machine;
        }
    }
}
